package com.api.interceptor;

import com.api.MErrorEnum;
import com.base.Const;
import com.base.CoreConstants;
import com.base.api.ApiException;
import com.base.api.SignAuth;
import com.base.api.annotation.ApiMethod;
import com.base.api.annotation.WxMethod;
import com.base.api.interceptor.AuthValidator;
import com.base.cache.CacheSupport;
import com.base.cache.CacheUtil;
import com.base.util.DateUtil;
import com.base.util.RequestKit;
import com.base.util.StringUtil;
import com.base.web.ParameterRequestWrapper;
import com.item.dao.model.MobileVerify;
import com.item.dao.model.User;
import com.item.service.CodeService;
import com.item.service.MobileVerifyService;
import com.item.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

@Component
public class ApiAuth extends SignAuth implements AuthValidator {

    @Autowired
    private MobileVerifyService mobileVerifyService;
    @Autowired
    private UserService userService;
    @Autowired
    private CodeService codeService;

    private static final int NICK_LENGTH = 30;

    private static final String TOKEN = "token";
    private static final String USER_ID = "userid";
    private static final String DEVICE_ID = "deviceid";
    private static final String DEVICE_TYPE = "deviceType";

    private static final String TIMESTAMP = "_timestamp";
    private static final long API_TIME = 1000;

    @Override
    public boolean validate(ApiMethod annotation, HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
        response.setHeader("Access-Control-Allow-Origin","*");
        //签名确认
//        if (annotation.isAuth() && !checkTimeSign(request)){
//            throw new ApiException(MErrorEnum.TIME_AUTH_FAIL_ERROR);
//        }
        //需要签名认证的接口加上ApiAuth
        com.api.anno.ApiAuth apiAuth = handlerMethod.getMethodAnnotation(com.api.anno.ApiAuth.class);
        if (apiAuth != null){
            if (!authVerify(request)){
                throw new ApiException(MErrorEnum.AUTH_FAIL_ERROR);
            }
        }

        //从header中获取token
        String token = request.getHeader(TOKEN);
        //如果header中不存在token，则从参数中获取token
        if(StringUtils.isBlank(token)){
            token = request.getParameter(TOKEN);
        }

        //分页
        if (annotation.isPage()){
            String p = request.getParameter(Const.PAGE);
            String l = request.getParameter(Const.LIMIT);
            if (StringUtils.isBlank(p) || StringUtils.isBlank(l)){
                throw new ApiException(MErrorEnum.PAGE_LIMIT_NONG);
            }
        }

        MobileVerify mobileVerify = null;

        if (StringUtils.isNotBlank(token)){
            mobileVerify = CacheSupport.get(CacheUtil.MOBILE_VERIFY_CACHE, token, MobileVerify.class);
            if (mobileVerify == null){
                mobileVerify = mobileVerifyService.queryByToken(token);
                if (mobileVerify != null){
                    CacheSupport.put(CacheUtil.MOBILE_VERIFY_CACHE, token, mobileVerify);
                }
            }

        }

        //登陆
        if(annotation.isLogin()){
            if(mobileVerify == null || (mobileVerify.getExpireTime() != null && mobileVerify.getExpireTime().getTime() < System.currentTimeMillis())){
                throw new ApiException(MErrorEnum.LOGIN_FAIL_ERROR);
            }
            if (mobileVerify.getDeviceId().endsWith("@store")){

            }else{
                User user = userService.selectByPrimaryKey(mobileVerify.getUserId());
                if(user == null){
                    throw new ApiException(MErrorEnum.USER_NOEXIST_ERROR);
                }
//                if(user.getUserType() == 0){
//                    throw new ApiException(MErrorEnum.ACCOUNT_STOP_ERROR);
//                }
            }
        }

        if (mobileVerify != null){
            if(mobileVerify.getExpireTime() != null){
                Date date = new Date();
                mobileVerify.setExpireTime(DateUtil.addMinute(date, 30));
                mobileVerify.setUpdateTime(date);
                mobileVerifyService.updateByPrimaryKey(mobileVerify);
                CacheSupport.put(CacheUtil.MOBILE_VERIFY_CACHE, token, mobileVerify);
            }
            ParameterRequestWrapper wrapper =  (ParameterRequestWrapper) request;
            wrapper.addParameter(USER_ID, mobileVerify.getUserId());
            wrapper.addParameter(DEVICE_ID, mobileVerify.getDeviceId());
            wrapper.addParameter(DEVICE_TYPE, mobileVerify.getDeviceType());
        }

        return true;
    }

    public boolean authVerify(HttpServletRequest request){
        Map<String,String> paramMap = RequestKit.getFromRequest(request);
        return authVerify(paramMap);
    }

    /**
     * 签名认证
     * @param paramMap
     * @return
     */
    public boolean authVerify(Map<String,String> paramMap){
        String key = codeService.getApiKey();
        if (StringUtil.isBlank(key)){
            return true;
        }
        String sign = paramMap.get(CoreConstants.SIGN);
        if (StringUtils.isBlank(sign)) return false;
        String verifySign = createSign(paramMap,key);
        return sign.equals(verifySign);
    }

    /**
     * 微信小程序接口
     * @param apiMethod
     * @param request
     * @param response
     * @param handlerMethod
     * @return
     */
    @Override
    public boolean validateWx(WxMethod apiMethod, HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
        return false;
    }
}
